package castledefense.logic.pathfinding;

import pathfinding.grid.GridLocation;
import pathfinding.grid.GridMap;
import pathfinding.grid.GridPath;
import pathfinding.grid.GridPathfindingFlood;
import castledefense.logic.Map;
import castledefense.util.Log;

public class Pathfinding {

	protected LinkForPathfinding link;

	protected final GridMap gridMap;
	private final GridPathfindingFlood pathfinding;
	
	protected final int[][] movementMap;

	public Pathfinding(LinkForPathfinding link) {
		this.link = link;
		gridMap = new GridMap(link.getMapSizeX(), link.getMapSizeY());
		movementMap = new int[link.getMapSizeX()][link.getMapSizeY()];
		pathfinding = new GridPathfindingFlood(gridMap, new GridLocation(link.getCastleX(), link.getCastleY(), true, 1));
	}

	public static double getMovementValue(int value, int type) {
		double n = 1;
		if (value == Map.empty) {
			n = 1;
		} else if (value == Map.openGate) {
			n = 1;
		} else if (value == Map.full || value == Map.wall) {
			n = GridMap.WALL;
		} else if (value == Map.unbuildable) {
			n = 1;
		}
		return n;
	}

	protected void generateMovementMap(int type) {
		for (int i = 0; i < link.getMapSizeX(); i++) {
            for (int j = 0; j < link.getMapSizeY(); j++) {
                    movementMap[i][j] = link.getConstructionMapValue(i, j);
            }
		}
		for (int i = 0; i < gridMap.getSizeX(); i++) {
			for (int j = 0; j < gridMap.getSizeY(); j++) {
				if(gridMap.get(i, j) != getMovementValue(movementMap[i][j], type)){
					gridMap.set(i, j, getMovementValue(movementMap[i][j], type));
				}
			}
		}
	}

	public GridPath getPath(PositionMover position, int endX, int endY) {
		int startX = position.getX();
		int startY = position.getY();

		return getPath(startX, startY, endX, endY, position.getType());
	}


	public GridPath getPath(int startX, int startY, int endX, int endY, int type) {
		generateMovementMap(type);
		
		GridLocation startLocation = new GridLocation(startX, startY, false,
				gridMap.get(startX, startY));
		GridLocation endLocation = new GridLocation(endX, endY, true,
				gridMap.get(endX, endY));
		
		Log.startTimerMicro();
		GridPath path = pathfinding.getPath(startLocation, endLocation, gridMap);
		int time = Log.stopTimerMicro();
		Log.g2("Time to find a path unit : " + time + " microseconds");
		return path;
	}

}
